<html>
<head><meta charset="utf-8"><title>Arc::into_raw and &amp;Arc · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Arc.3A.3Ainto_raw.20and.20.26Arc.html">Arc::into_raw and &amp;Arc</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="231999514"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Arc%3A%3Ainto_raw%20and%20%26Arc/near/231999514" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> marmeladema <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Arc.3A.3Ainto_raw.20and.20.26Arc.html#231999514">(Mar 26 2021 at 17:01)</a>:</h4>
<p>Hello!<br>
I am writing various C-compatible API where sometime I return pointer that are coming from Arc::into_raw. I sometime need to then pass that pointer back to rust and work on that Arc to retrieve a weak pointer to it.<br>
I am currently dancing with:</p>
<div class="codehilite"><pre><span></span><code>let arc = Arc::from_raw(ptr);
let weak = Arc::downgrade(&amp;arc);
Arc::into_raw(arc);
do_something_with(weak);
</code></pre></div>
<p>I wonder if there is a more idiomatic way to retrieve a <code>&amp;Arc&lt;T&gt;</code> from a pointer that comes from <code>Arc&lt;T&gt;::into_raw</code>?</p>



<a name="232001629"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Arc%3A%3Ainto_raw%20and%20%26Arc/near/232001629" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Arc.3A.3Ainto_raw.20and.20.26Arc.html#232001629">(Mar 26 2021 at 17:15)</a>:</h4>
<p>There's also <code>Weak::from_raw</code></p>



<a name="232001766"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Arc%3A%3Ainto_raw%20and%20%26Arc/near/232001766" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Arc.3A.3Ainto_raw.20and.20.26Arc.html#232001766">(Mar 26 2021 at 17:16)</a>:</h4>
<p>I guess it's not explicit that <code>Arc::into_raw</code> and <code>Weak::into_raw</code> return compatible pointers, but logically they must</p>



<a name="232001879"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Arc%3A%3Ainto_raw%20and%20%26Arc/near/232001879" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Arc.3A.3Ainto_raw.20and.20.26Arc.html#232001879">(Mar 26 2021 at 17:16)</a>:</h4>
<p>oh, but the counts would not be correct</p>



<a name="232002276"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Arc%3A%3Ainto_raw%20and%20%26Arc/near/232002276" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Arc.3A.3Ainto_raw.20and.20.26Arc.html#232002276">(Mar 26 2021 at 17:19)</a>:</h4>
<p>Arc::downgrade(&amp;*ManuallyDrop::new(Arc::from_raw(ptr)))</p>



<a name="232002909"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Arc%3A%3Ainto_raw%20and%20%26Arc/near/232002909" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> marmeladema <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Arc.3A.3Ainto_raw.20and.20.26Arc.html#232002909">(Mar 26 2021 at 17:23)</a>:</h4>
<p>Would ManuallyDrop be better that what I am currently doing?</p>



<a name="232003106"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Arc%3A%3Ainto_raw%20and%20%26Arc/near/232003106" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> marmeladema <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Arc.3A.3Ainto_raw.20and.20.26Arc.html#232003106">(Mar 26 2021 at 17:25)</a>:</h4>
<p>It seems cleaner</p>



<a name="232005151"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Arc%3A%3Ainto_raw%20and%20%26Arc/near/232005151" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Arc.3A.3Ainto_raw.20and.20.26Arc.html#232005151">(Mar 26 2021 at 17:37)</a>:</h4>
<p><code>ManuallyDrop</code> sort of hides the temporary local ownership</p>



<a name="232005227"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Arc%3A%3Ainto_raw%20and%20%26Arc/near/232005227" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Arc.3A.3Ainto_raw.20and.20.26Arc.html#232005227">(Mar 26 2021 at 17:37)</a>:</h4>
<p>I think it would be possible to add some <code>unsafe fn(&amp;*const T) -&gt; &amp;Arc&lt;T&gt;</code>, because <code>Arc</code> itself is basically just a pointer</p>



<a name="232005397"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Arc%3A%3Ainto_raw%20and%20%26Arc/near/232005397" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Arc.3A.3Ainto_raw.20and.20.26Arc.html#232005397">(Mar 26 2021 at 17:39)</a>:</h4>
<p>or maybe there should just be a <code>downgrade_raw</code></p>



<a name="232011268"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Arc%3A%3Ainto_raw%20and%20%26Arc/near/232011268" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> marmeladema <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Arc.3A.3Ainto_raw.20and.20.26Arc.html#232011268">(Mar 26 2021 at 18:23)</a>:</h4>
<p>Ideally for my use cases, I would really like a <code>unsafe fn(&amp;*const T) -&gt; &amp;Arc&lt;T&gt;</code> because it's not only to call downgrade. I have objects that implement certain method only if they are in an arc and sometime I want to get arc properties like strong_count etc; So that solution seems better than a very targeted <code>downgrade_raw</code></p>



<a name="232012249"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Arc%3A%3Ainto_raw%20and%20%26Arc/near/232012249" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Arc.3A.3Ainto_raw.20and.20.26Arc.html#232012249">(Mar 26 2021 at 18:31)</a>:</h4>
<p>hmm, <code>from_raw</code> has to offset the pointer, so it's not as simple as I hoped</p>



<a name="232012350"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Arc%3A%3Ainto_raw%20and%20%26Arc/near/232012350" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Arc.3A.3Ainto_raw.20and.20.26Arc.html#232012350">(Mar 26 2021 at 18:31)</a>:</h4>
<p><code>&amp;Arc&lt;T&gt;</code> has to borrow from something, and it can't directly repurpose <code>&amp;*const T</code> after all</p>



<a name="232020781"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Arc%3A%3Ainto_raw%20and%20%26Arc/near/232020781" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Arc.3A.3Ainto_raw.20and.20.26Arc.html#232020781">(Mar 26 2021 at 19:38)</a>:</h4>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">unsafe</span><span class="w"></span>
<span class="k">fn</span> <span class="nf">arc_ref_from_raw</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="nb">_</span> <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">T</span><span class="p">)</span><span class="w"></span>
<span class="w">  </span>-&gt; <span class="nc">impl</span><span class="w"> </span><span class="o">'</span><span class="nb">_</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">Deref</span><span class="o">&lt;</span><span class="n">Target</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Arc</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">ManuallyDrop</span>::<span class="n">new</span><span class="p">(</span><span class="n">Arc</span>::<span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span>::<span class="n">from_raw</span><span class="p">(</span><span class="n">p</span><span class="p">))</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>or with CPS style:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">unsafe</span><span class="w"></span>
<span class="k">fn</span> <span class="nf">with_arc_ref_from_raw</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">R</span><span class="o">&gt;</span><span class="w"> </span><span class="p">(</span><span class="w"></span>
<span class="w">    </span><span class="n">p</span>: <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">T</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">ret</span>: <span class="nc">impl</span><span class="w"> </span><span class="k">for</span><span class="o">&lt;'</span><span class="na">ret</span><span class="o">&gt;</span><span class="w"> </span><span class="nb">FnOnce</span><span class="p">(</span><span class="o">&amp;'</span><span class="na">ret</span><span class="w"> </span><span class="n">Arc</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">R</span><span class="p">,</span><span class="w"></span>
<span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">R</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">ret</span><span class="p">(</span><span class="o">&amp;</span><span class="n">ManuallyDrop</span>::<span class="n">new</span><span class="p">(</span><span class="n">Arc</span>::<span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span>::<span class="n">from_raw</span><span class="p">(</span><span class="n">p</span><span class="p">)))</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>Examples:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">unsafe</span><span class="w"></span>
<span class="k">fn</span> <span class="nf">inc_ref</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">(</span><span class="n">p</span>: <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">T</span><span class="p">)</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">mem</span>::<span class="n">forget</span><span class="p">(</span><span class="n">Arc</span>::<span class="n">clone</span><span class="p">(</span><span class="n">arc_ref_from_raw</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p</span><span class="p">)))</span><span class="w"></span>
<span class="w">    </span><span class="c1">// or</span>
<span class="w">    </span><span class="n">mem</span>::<span class="n">forget</span><span class="p">(</span><span class="n">with_arc_ref_from_raw</span><span class="p">(</span><span class="n">p</span><span class="p">,</span><span class="w"> </span><span class="o">|</span><span class="n">arc_ref</span><span class="o">|</span><span class="w"> </span><span class="n">arc_ref</span><span class="p">.</span><span class="n">clone</span><span class="p">()))</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>